/*
 *Copyright (c) 2024 Black Sesame Technologies
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
*/

#ifndef STANDARDTYPES_H
#define STANDARDTYPES_H

#ifdef __cplusplus
extern "C"{
#endif

/*==================================================================================================
*                                         INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
//#include "StandardTypes.h"


#include "../../library/types.h"


/*==================================================================================================
                                      FILE VERSION CHECKS
==================================================================================================*/

#include "../../library/printf_inc.h"

/*==================================================================================================
 *                               SOURCE FILE VERSION INFORMATION
 ==================================================================================================*/

/*==================================================================================================
 *                                      FILE VERSION CHECKS
 ==================================================================================================*/

/*==================================================================================================
 *                                           CONSTANTS
 ==================================================================================================*/

/*==================================================================================================
 *                                       DEFINES AND MACROS
 ==================================================================================================*/
#ifndef TRUE
/**
 * @brief Boolean true value
 */
#define TRUE 1
#endif

#ifndef FALSE
/**
 * @brief Boolean false value
 */
#define FALSE 0
#endif

/*==================================================================================================
                         ENUMS
 ==================================================================================================*/

/*==================================================================================================
                 STRUCTURES AND OTHER TYPEDEFS
 ==================================================================================================*/


/**
 * @brief The standard AUTOSAR type boolean shall be implemented on basis of
 * an eight bits long  unsigned integer.
 */
typedef unsigned char boolean;

/**
 * @brief Unsigned 8 bit integer with range of
 * 0 ..+255 (0x00..0xFF) - 8 bit
 */
typedef unsigned char uint8;

/**
 * @brief Unsigned 16 bit integer with range of
 * 0 ..+65535 (0x0000..0xFFFF) - 16 bit
 */
typedef unsigned short uint16;

/**
 * @brief Unsigned 32 bit integer with range of
 * 0 ..+4294967295 (0x00000000..0xFFFFFFFF) - 32 bit
 */
//typedef unsigned long uint32;

/**
 * @brief Unsigned 64 bit integer with range of
 * 0..18446744073709551615 (0x0000000000000000..0xFFFFFFFFFFFFFFFF)- 64 bit
 *
 */
typedef unsigned long long uint64;

/**
 * @brief Signed 8 bit integer with range of
 * -128 ..+127 (0x80..0x7F) - 7 bit + 1 sign bit
 */
typedef signed char sint8;

/**
 * @brief Signed 16 bit integer with range of
 * -32768 ..+32767 (0x8000..0x7FFF) - 15 bit + 1 sign bit
 */
typedef signed short sint16;

/**
 * @brief Signed 32 bit integer with range of
 * -2147483648.. +2147483647 (0x80000000..0x7FFFFFFF) - 31 bit + 1 sign bit
 */
//typedef signed long sint32;

/**
 * @brief Signed 64 bit integer with range of
 * -9223372036854775808..9223372036854775807 :
 * (0x8000000000000000..0x7FFFFFFFFFFFFFFF ) : 63 bit + 1 sign bit
 *
 */
typedef signed long long sint64;


/*==================================================================================================
                                           CONSTANTS
==================================================================================================*/
/**
* @brief Physical state 5V or 3.3V
* @implements SymbolDefinitions_enum
*/
#ifndef STD_HIGH
#define STD_HIGH    0x01
#endif

/**
* @brief Physical state 0V.
* @implements SymbolDefinitions_enum
*/
#ifndef STD_LOW
#define STD_LOW     0x00
#endif

/**
* @brief Logical state active.
* @implements SymbolDefinitions_enum
*/
#define STD_ACTIVE  0x01

/**
* @brief Logical state idle.
* @implements SymbolDefinitions_enum
*/
#define STD_IDLE    0x00

/**
* @brief ON State.
* @implements SymbolDefinitions_enum
*/
#define STD_ON      0x01

/**
* @brief OFF state.
* @implements SymbolDefinitions_enum
*/
#define STD_OFF     0x00

/**
* @brief Return code for failure/error.
* @implements SymbolDefinitions_enum
*/
#ifndef E_NOT_OK
#define E_NOT_OK    0x01
#endif

#ifndef STATUSTYPEDEFINED
    #define STATUSTYPEDEFINED
    /**
    * @brief Success return code
    */
    #define E_OK      0x00

#endif

/**
* @brief This type can be used as standard API return type which is shared between the RTE and the
*        BSW modules.
*/
/* @implements Std_ReturnType_type */
typedef uint8 Std_ReturnType;




/*==================================================================================================
 *                                      DEFINES AND MACROS
 ==================================================================================================*/
/**
 * Convert existing macros into corresponding function names for
 * backward compatibility
 */
#undef REG_WRITE8
#undef REG_WRITE16
#undef REG_WRITE32
#undef REG_READ8
#undef REG_READ16
#undef REG_READ32
#undef REG_AWRITE8
#undef REG_AWRITE16
#undef REG_AWRITE32
#undef REG_AREAD8
#undef REG_AREAD16
#undef REG_AREAD32
#undef REG_BIT_CLEAR8
#undef REG_BIT_CLEAR16
#undef REG_BIT_CLEAR32
#undef REG_BIT_GET8
#undef REG_BIT_GET16
#undef REG_BIT_GET32
#undef REG_BIT_SET8
#undef REG_BIT_SET16
#undef REG_BIT_SET32
#undef REG_RMW8
#undef REG_RMW16
#undef REG_RMW32

#define REG_WRITE8 Reg_Write8
#define REG_WRITE16 Reg_Write16
#define REG_WRITE32 Reg_Write32
#define REG_READ8 Reg_Read8
#define REG_READ16 Reg_Read16
#define REG_READ32 Reg_Read32
#define REG_AWRITE8 Reg_Awrite8
#define REG_AWRITE16 Reg_Awrite16
#define REG_AWRITE32 Reg_Awrite32
#define REG_AREAD8 Reg_Aread8
#define REG_AREAD16 Reg_Aread16
#define REG_AREAD32 Reg_Aread32
#define REG_BIT_CLEAR8 Reg_Bit_Clear8
#define REG_BIT_CLEAR16 Reg_Bit_Clear16
#define REG_BIT_CLEAR32 Reg_Bit_Clear32
#define REG_BIT_GET8 Reg_Bit_Get8
#define REG_BIT_GET16 Reg_Bit_Get16
#define REG_BIT_GET32 Reg_Bit_Get32
#define REG_BIT_SET8 Reg_Bit_Set8
#define REG_BIT_SET16 Reg_Bit_Set16
#define REG_BIT_SET32 Reg_Bit_Set32
#define REG_RMW8 Reg_Rmw8
#define REG_RMW16 Reg_Rmw16
#define REG_RMW32 Reg_Rmw32


/*==================================================================================================
*                                     FUNCTION PROTOTYPES
==================================================================================================*/
#ifndef __DOXYGEN__
/**
 * @brief 8 bits memory write function
 */
#endif
static inline void Reg_Write8(uint32 address, uint8 value)
{
    *(volatile uint8 *)(address) = value;
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits memory write function.
 */
#endif
static inline void Reg_Write16(uint32 address, uint16 value)
{
    *(volatile uint16 *)(address) = value;
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits memory write function.
 */
#endif
static inline void Reg_Write32(uint32 address, uint32 value)
{
    *(volatile uint32 *)(address) = value;
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bits memory read function.
 */
#endif
static inline uint8 Reg_Read8(uint32 address)
{
    return (*(volatile uint8 *)(address));
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits memory read function.
 */
#endif
static inline uint16 Reg_Read16(uint32 address)
{
    return (*(volatile uint16 *)(address));
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits memory read function.
 */
#endif
static inline uint32 Reg_Read32(uint32 address)
{
    return (*(volatile uint32 *)(address));
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bits indexed memory write function.
 * Index i must have the data type uint32.
 */
#endif
static inline void Reg_Awrite8(uint32 address, uint32 i, uint8 value)
{
    *(volatile uint8 *)(address + i) = value;
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits indexed memory write function.
 * Index i must have the data type uint32.
 */
#endif
static inline void Reg_Awrite16(uint32 address, uint32 i, uint16 value)
{
    *(volatile uint16 *)(address + i) = value;
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits indexed memory write function.
 * Index i must have the data type uint32.
 */
#endif
static inline void Reg_Awrite32(uint32 address, uint32 i, uint32 value)
{
    *(volatile uint32 *)(address + i) = value;
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bits indexed memory read function.
 * Index i must have the data type uint32.
 */
#endif
static inline uint8 Reg_Aread8(uint32 address, uint32 i)
{
    return (*(volatile uint8 *)(address + i));
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits indexed memory read function.
 * Index i must have the data type uint32.
 */
#endif
static inline uint16 Reg_Aread16(uint32 address, uint32 i)
{
    return (*(volatile uint16 *)(address + ((uint32)(i << 1U))));
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits indexed memory read function.
 * Index i must have the data type uint32.
 */
#endif
static inline uint32 Reg_Aread32(uint32 address, uint32 i)
{
    return (*(volatile uint32 *)(address + ((uint32)(i << 2U))));
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bits bits clearing function.
 */
#endif
static inline void Reg_Bit_Clear8(uint32 address, uint8 mask)
{
    (*(volatile uint8 *)(address)) &= (~(mask));
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits bits clearing function.
 */
#endif
static inline void Reg_Bit_Clear16(uint32 address, uint16 mask)
{
    (*(volatile uint16 *)(address)) &= (~(mask));
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits bits clearing function.
 */
#endif
static inline void Reg_Bit_Clear32(uint32 address, uint32 mask)
{
    (*(volatile uint32 *)(address)) &= (~(mask));
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bits bits getting function.
 */
#endif
static inline uint8 Reg_Bit_Get8(uint32 address, uint8 mask)
{
    return ((*(volatile uint8 *)(address)) & (mask));
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits bits getting function.
 */
#endif
static inline uint16 Reg_Bit_Get16(uint32 address, uint16 mask)
{
    return ((*(volatile uint16 *)(address)) & (mask));
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits bits getting function.
 */
#endif
static inline uint32 Reg_Bit_Get32(uint32 address, uint32 mask)
{
    return ((*(volatile uint32 *)(address)) & (mask));
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bits bits setting function.
 */
#endif
static inline void Reg_Bit_Set8(uint32 address, uint8 mask)
{
    *(volatile uint8 *)(address) |= mask;
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bits bits setting function.
 */
#endif
static inline void Reg_Bit_Set16(uint32 address, uint16 mask)
{
    *(volatile uint16 *)(address) |= mask;
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bits bits setting function.
 */
#endif
static inline void Reg_Bit_Set32(uint32 address, uint32 mask)
{
    *(volatile uint32 *)(address) |= mask;
}

#ifndef __DOXYGEN__
/**
 * @brief 8 bit clear bits and set with new value
 * @note In the current implementation, it is caller's (user's) responsability
 *       to make sure that value has only "mask" bits set - (value&~mask)==0
 */
#endif
static inline void Reg_Rmw8(uint32 address, uint8 mask, uint8 value)
{
    *(volatile uint8 *)(address) =
        (*(volatile uint8 *)(address) & ((uint8) ~(mask))) | value;
}

#ifndef __DOXYGEN__
/**
 * @brief 16 bit clear bits and set with new value
 * @note In the current implementation, it is caller's (user's) responsability
 *       to make sure that value has only "mask" bits set - (value&~mask)==0
 */
#endif
static inline void Reg_Rmw16(uint32 address, uint16 mask, uint16 value)
{
    *(volatile uint16 *)(address) =
        (*(volatile uint16 *)(address) & ((uint16) ~(mask))) | value;
}

#ifndef __DOXYGEN__
/**
 * @brief 32 bit clear bits and set with new value
 * @note In the current implementation, it is caller's (user's) responsability
 *       to make sure that value has only "mask" bits set - (value&~mask)==0
 */
#endif
static inline void Reg_Rmw32(uint32 address, uint32 mask, uint32 value)
{
    *(volatile uint32 *)(address) =
        (*(volatile uint32 *)(address) & ((uint32) ~(mask))) | value;
}

#ifdef __cplusplus
}
#endif

#endif /* #ifndef STANDARDTYPES_H */

/** @} */
